/**
 * 
 * @author Ryan Diaz, Kevin Curtin
 *
 */
public class Node<T> {
	public T data;
    public Node<T> left;
    public Node<T> right;
    public Node<T> parent;
    public int color;
    
    /**
       Constructs a red node with no data.
    */
    public Node() {}
    
    /**
       Sets the left child and updates its parent pointer.
       @param child the new left child
    */
    public void setLeftChild(Node<T> child)
    {
       left = child;
       if (child != null) { child.parent = this; }
    }
    
    /**
       Sets the right child and updates its parent pointer.
       @param child the new right child
    */
    public void setRightChild(Node<T> child)
    {
       right = child;
       if (child != null) { child.parent = this; }
    }
    
    /**
     * Updates the parent's and replacement node's links when this node is replaced.
     * @param replacement the node that replaces this node
     */
    public void replaceWith(Node<T> replacement)
    {
  	  if (parent == null) return;
  	  if (this == parent.left) parent.setLeftChild(replacement);
  	  else parent.setRightChild(replacement);
    }
    
    /**
       Inserts a new node as a descendant of this node.
       @param newNode the node to insert
    */
    public void addNode(Node<T> newNode)
    {  
       int comp = ((Comparable) newNode.data).compareTo(data);
       if (comp < 0)
       {  
          if (left == null) 
          {
             left = newNode;
             left.parent = this;
          }
          else { left.addNode(newNode); }
       }
       else if (comp > 0)
       {  
          if (right == null) 
          {
             right = newNode;
             right.parent = this;
          }
          else { right.addNode(newNode); }
       }
    }
}
